namespace GYLite{
    export class GYBitmap extends egret.Bitmap implements IUpdate,IBatch,IResource{
		public gyliteFill:boolean;
		protected _batchDrawParam:BatchDrawParam;        
		private _batchAtlasName:string;
		private _batch:boolean;
		protected _invalidBatch:boolean;
		/**是否刷新中（内部使用请勿修改）*/
		public updating:boolean;

		protected _WMidData:egret.Texture;
		protected _HMidData:egret.Texture;
		
		protected _imgWidth:number;
		protected _imgHeight:number;
		protected _scale9GridRect:Scale9GridRect;
		protected _clipX:number;
		protected _clipY:number;
		protected _drawX:number;
		protected _drawY:number;
		protected _mode:number;		
		protected _invalidDraw:boolean;		
		protected _renderMatrix:egret.Matrix;
		protected _repeat:boolean;
		protected _repeatWidth:number;
		protected _repeatHeight:number;
		protected _repeatX:number;
		protected _repeatY:number;
		protected _width:number;
		protected _height:number;
		protected _batchTexture:egret.Texture;
		protected _normalNode:egret.sys.NormalBitmapNode;
		protected _bitmapNode:egret.sys.BitmapNode;
		constructor(value?: egret.Texture,rect:Scale9GridRect=null,batch:boolean=true){
			super();//先把变量初始化再初始化texture
			var s = this;									
			s._clipX = 0;
			s._clipY = 0;
			s._drawX = 0;
			s._drawY = 0;
			s._invalidDraw = false;
			s._mode = ScaleMode.SCALE;			
			s._repeatX = 0;
			s._repeatY = 0;
			s._repeatWidth=NaN;
			s._repeatHeight=NaN;
			s._imgWidth = NaN;
			s._imgHeight = NaN;
			s._width = NaN;
			s._height = NaN;			
			s.enableBatch(batch);
			s.scale9GridRect = rect;
			s.texture = value;			
		}
		public clearBatch():void
		{
		}
		public $setTexture(val:egret.Texture):boolean
		{
			let flag:boolean;
			let oldTex:egret.Texture;
			let s= this;	
			if(s._normalNode == null)
			{
				s._normalNode = new egret.sys.NormalBitmapNode;
				s._bitmapNode = new egret.sys.BitmapNode;		
			}
			
			oldTex = s.$texture;
			if(oldTex != val)
				s.$renderNode = (s._mode == ScaleMode.FREE?s._normalNode:s._bitmapNode);
			flag = super.$setTexture(val);
			if(flag)
			{
				if(oldTex && oldTex.$batchManager)
					oldTex.$batchManager.removeDisplayBatch(s);
				if(val == null)
				{
					s.clearBitmapFill();				
					return;
				}									
				if(egret.nativeRender)
				{
					s._imgWidth=s.$texture.textureWidth;
					s._imgHeight=s.$texture.textureHeight;
				}
				else
				{
					s._imgWidth=s.$texture.$bitmapWidth;//$bitmapWidth和textureWidth是有区别的，textureWidth在图集中包括边距，是原始小图宽高，前者是裁切透明像素后的宽高,使用textureWidth会导致截取图集区域不准确
					s._imgHeight=s.$texture.$bitmapHeight;
				}
			}
			return flag;
		}
		public $refreshImageData():void
		{
			let s= this;			
			let texture:egret.Texture;
			if(s.isBatch())
				texture = AtlasRender.getBatchTexture(s.$texture,s);
			else
				texture = s.$texture;	
			s._batchTexture = texture;
            if (texture) {
                if (egret.nativeRender) {
                    s.setBitmapDataToWasm(texture);
                }
                s.setImageData(texture.$bitmapData, texture.$bitmapX, texture.$bitmapY, texture.$bitmapWidth, texture.$bitmapHeight, texture.$offsetX, texture.$offsetY, texture.$getTextureWidth(), texture.$getTextureHeight(), texture.$sourceWidth, texture.$sourceHeight);
            }
            else {
                if (egret.nativeRender) {
                    s.setBitmapDataToWasm(null);
                }
            }
			s.invalidDraw();
        }	
        public $updateRenderNode() {
			var s = this;
			if (s.$texture) {
				if(s.gyliteFill)
				{
					let node:egret.sys.BitmapNode = <egret.sys.BitmapNode>s.$renderNode;
                    node.smoothing = s.$smoothing;
                    node.image = s._batchTexture.$bitmapData;
                    node.imageWidth = s.$sourceWidth;
                    node.imageHeight = s.$sourceHeight;
					return;
				}
			}
            super.$updateRenderNode();
		}
		public invalidBatch():void
		{
			let s= this;
			if(s._invalidBatch)
				return;
			s._invalidBatch = true;
			LayoutManager.addRenderFunc(s);			
		}
		public enableBatch(val:boolean)
		{
			this._batch = val;			
		}
		/**是否动态合批，请在文本渲染前设定，默认根据父级容器batch，如果父级也没设定，则默认false*/
		public isBatch():boolean
		{
			let s = this;
			if(s._batch !== undefined)
				return s._batch;			
			let pr:GYSprite;
			pr = <GYSprite>s.$parent;			
			return pr && pr.isBatch && pr.isBatch();
		}		
		public setBatchDrawParam(val:BatchDrawParam):void
		{
			this._batchDrawParam = val;
		}
		/**合批图像的绘制样式**/
		public getBatchDrawParam():BatchDrawParam
		{
			return this._batchDrawParam;
		}
		
		public validBatch():void
		{
		}
		public updateView():void
		{
			var s = this;
			if(s._invalidBatch)
			{
				s.validBatch();
				s._invalidBatch = false;				
			}
			if(s._invalidDraw)
			{
				s.validDraw();
				s._invalidDraw = false;
			}
		}
		public setBatchAtlasName(val:string)
		{
			let s= this;
			s._batchAtlasName = val;			
		}
		/**合批图集名称，不存在找父级容器的，如果都不存在，默认AtlasRender.defaultAtlasName**/
		public getBatchAtlasName():string
		{
			let s = this;
			if(s._batchAtlasName!=null)
				return s._batchAtlasName;
			let pr:GYSprite;
			pr = <GYSprite>s.$parent;	
			return pr && pr.getBatchAtlasName?pr.getBatchAtlasName():AtlasRender.defaultAtlasName;;
		}
        public $getRenderNode() {
			let s = this;
			let node:egret.sys.RenderNode;
            node = s.$renderNode;
            if (!node) {
                return null;
            }
			if (s.$renderDirty) {
				let tex:egret.Texture;
				let batchInfo:BatchInfo;
				tex = s.texture;
				if(tex && tex.$batchManager && s.isBatch())
				{	
					batchInfo = tex.$batchManager.getBatchByDisplay(s);
					if(batchInfo)
						batchInfo.measureAndDraw();					
				}
				if(!s.gyliteFill)
					node.cleanBeforeRender();
                s.$updateRenderNode();
                s.$renderDirty = false;
                node = s.$renderNode;
			}
			return node;
		}
		
		
		public validDraw():void
		{
			let s= this;
			s.draw(s._batchTexture);
		}
		private draw(tex:egret.Texture):void
		{
			let s = this;						
			if(tex==null)
				return;	
			if(s._mode == ScaleMode.FREE)
			{				
				s.$renderDirty = true;
				return;
			}			
			var sclX:number,sclY:number;
			var tempY1:number,tempY2:number,tempY3:number,tempX1:number,tempX2:number,tempX3:number;			
			var destW:number,destH:number;
			var isGL:boolean;
			var topGap:number,bottomGap:number,leftGap:number,rightGap:number;
			var offsetX:number,offsetY:number,paddingW:number,paddingH:number;			
			var mustClip:boolean;
			
			paddingW = tex.textureWidth - tex.$bitmapWidth * egret.$TextureScaleFactor;
			paddingH = tex.textureHeight - tex.$bitmapHeight * egret.$TextureScaleFactor;			
			if(s._width == s._width)
				destW = s._width - paddingW;
			else
				destW = s._imgWidth;				
				
			if(s._height == s._height)
				destH = s._height - paddingH;				
			else
				destH = s._imgHeight;			
			if(egret.nativeRender)
			{
				if(s._scale9GridRect)
					s.scale9Grid = new egret.Rectangle(s._scale9GridRect.leftGap,s._scale9GridRect.topGap,s._imgWidth - s._scale9GridRect.leftGap - s._scale9GridRect.rightGap,s._imgHeight - s._scale9GridRect.bottomGap - s._scale9GridRect.topGap)
				else
					s.scale9Grid = null;
				if(s._mode == ScaleMode.SCALE || s._scale9GridRect)				
					s.fillMode = egret.BitmapFillMode.SCALE;
				else if(s._mode == ScaleMode.CLIP)
					s.fillMode = egret.BitmapFillMode.CLIP;
				else if(s._mode == ScaleMode.REPEAT)
					s.fillMode = egret.BitmapFillMode.REPEAT;
				return;
			}
			isGL = false;//egret.Capabilities.renderMode == "webgl" && CommonUtil.GYIs(tex, GYLite.GYDrawBitmapData);			
			s.clearBitmapFill();
			if(destW <= 0 || destH <= 0)
				return;
			if(s._scale9GridRect)
			{//九宫格减去图集小图透明像素偏移量
				offsetX = tex.$offsetX;
				offsetY = tex.$offsetY;			
				topGap = s._scale9GridRect.topGap - offsetY;
				bottomGap = s._scale9GridRect.bottomGap - paddingH + offsetY;
				leftGap = s._scale9GridRect.leftGap - offsetX;
				rightGap = s._scale9GridRect.rightGap - paddingW + offsetX;
			}
			
			mustClip = s._scale9GridRect && (destW < leftGap + rightGap || destH < topGap + bottomGap);//不符合九宫格条件，强制裁切	
			if(mustClip && (destW > s._imgWidth || destH > s._imgHeight))return;//小于原图大小，不绘制
			if(s._scale9GridRect == null || mustClip)
			{				
				GYSprite._matrix.a=1;
				GYSprite._matrix.d=1;
				GYSprite._matrix.tx=s._drawX-s._clipX;
				GYSprite._matrix.ty=s._drawY-s._clipY;
				if(s._mode == ScaleMode.CLIP || mustClip)
					s.beginBitmapFill(GYSprite._matrix,false);
				else if(s._mode == ScaleMode.SCALE)
				{
					GYSprite._matrix.a=destW / s._imgWidth;
					GYSprite._matrix.d=destH / s._imgHeight;
					s.beginBitmapFill(GYSprite._matrix,false);
				}
				else
				{	
					s.beginBitmapFill(GYSprite._matrix,true);									
				}								
				s.drawRect(s._drawX,s._drawY,destW+1,destH+1);//多画一像素保证内容完整,egret渲染问题
				return;
			}			
			tempX1=destW-rightGap;
			tempX2=tempX1-leftGap;
			tempX3=destW-s._imgWidth;
			tempY1=destH-bottomGap;
			tempY2=tempY1-topGap;
			tempY3=destH-s._imgHeight;
			
			sclX=tempX2/(s._imgWidth-leftGap-rightGap);
			sclY=tempY2/(s._imgHeight-topGap-bottomGap);
			// toX=(sclX-1)*leftGap;
			// toY=(sclY-1)*topGap;
			//拉伸头部
			GYSprite._matrix.a=sclX;
			GYSprite._matrix.d=1;
			GYSprite._matrix.tx=0;//-toX;
			GYSprite._matrix.ty=(isGL?-s._imgHeight+topGap:0);
			s.beginBitmapFill(GYSprite._matrix,false);									
			s.drawRect(leftGap, 0, tempX2, topGap);	
			
			//拉伸左部
			GYSprite._matrix.a=1;
			GYSprite._matrix.d=sclY;
			GYSprite._matrix.tx=0;
			GYSprite._matrix.ty=0;//-toY;
			s.beginBitmapFill(GYSprite._matrix,false);
			s.drawRect(0, topGap, leftGap, tempY2);
			//拉伸中部
			GYSprite._matrix.a=sclX;
			GYSprite._matrix.d=sclY;
			GYSprite._matrix.tx=0;//-toX;
			GYSprite._matrix.ty=0;//-toY;
			s.beginBitmapFill(GYSprite._matrix,false);
			s.drawRect(leftGap, topGap, tempX2, tempY2);
			//拉伸脚部
			GYSprite._matrix.a=sclX;
			GYSprite._matrix.d=1;
			GYSprite._matrix.tx=0;//-toX;			
			GYSprite._matrix.ty=(isGL?tempY1:tempY3);			
			s.beginBitmapFill(GYSprite._matrix,false);
			s.drawRect(leftGap, tempY1, tempX2, bottomGap);
			//拉伸右部
			GYSprite._matrix.a=1;
			GYSprite._matrix.d=sclY;
			GYSprite._matrix.tx=tempX3;
			GYSprite._matrix.ty=0;//-toY;
			s.beginBitmapFill(GYSprite._matrix,false);
			s.drawRect(tempX1, topGap,  rightGap, tempY2);
			//四角
			GYSprite._matrix.a=1;
			GYSprite._matrix.d=1;
			GYSprite._matrix.tx=0;
			GYSprite._matrix.ty=(isGL?-s._imgHeight+topGap:0);
			s.beginBitmapFill(GYSprite._matrix,false);
			s.drawRect(0, 0, leftGap, topGap);
			GYSprite._matrix.tx=tempX3;
			GYSprite._matrix.ty=(isGL?-s._imgHeight+topGap:0);
			s.beginBitmapFill(GYSprite._matrix,false);
			s.drawRect(tempX1, 0, rightGap, topGap);
			GYSprite._matrix.tx=0;
			GYSprite._matrix.ty=(isGL?tempY1:tempY3);
			s.beginBitmapFill(GYSprite._matrix,false);
			s.drawRect(0, tempY1, leftGap, bottomGap);
			GYSprite._matrix.tx=tempX3;
			GYSprite._matrix.ty=(isGL?tempY1:tempY3);
			s.beginBitmapFill(GYSprite._matrix,false);
			s.drawRect(tempX1, tempY1, rightGap, bottomGap);						
		}		
		public beginBitmapFill(m:egret.Matrix, r:boolean):void
		{
			var s = this;			
			if(egret.nativeRender)
				throw(new Error("runTime模式不支持！beginBitmapFill"));			
			s.gyliteFill = true;//位图填充标志			
			if(m)
			{
				if(s._renderMatrix == null)
					s._renderMatrix = egret.Matrix.create();
				s._renderMatrix.copyFrom(m);
			}				
			else
			{
				egret.Matrix.release(s._renderMatrix);				
				s._renderMatrix = null;
			}
				
			
			s._repeat = r;
		}
		public drawRect(tX:number, tY:number, w:number, h:number):void
		{
			var s = this;
			if(egret.nativeRender)
				throw(new Error("runTime模式不支持！drawRect"));
			var node:any = s.$renderNode;
			var sclX:number,sclY:number;
			var displayWidth:number,displayHeight:number, stepWidth:number,stepHeight:number;
			var startX:number,startY:number,paddingX:number,paddingY:number;	
			var i:number,iLen:number,j:number,jLen:number,tempX:number;			
			var batchTexture:egret.Texture;
			batchTexture = s._batchTexture;
			if(s._repeat)
			{
				sclX = s._renderMatrix.a;
				sclY = s._renderMatrix.d;
				displayWidth = (isNaN(s._repeatWidth)?s._imgWidth:s._repeatWidth)*sclX;
				displayHeight = (isNaN(s._repeatHeight)?s._imgHeight:s._repeatHeight)*sclY;
				paddingX = s._renderMatrix.tx % displayWidth;
				paddingY = s._renderMatrix.ty % displayHeight;				
				paddingX = (paddingX <= 0?-paddingX:displayWidth - paddingX);
				paddingY = (paddingY <= 0?-paddingY:displayHeight - paddingY);			
				startY = tY;				
				jLen = Math.ceil((paddingX + w) / displayWidth);
				iLen = Math.ceil((paddingY + h) / displayHeight);
				for (i = 0; i < iLen; ++i) {
					stepHeight = displayHeight - paddingY;
					stepHeight = Math.min(h - startY + tY, stepHeight);
					tempX = paddingX;	
					startX = tX;			
					for (j = 0; j < jLen; ++j) {
						stepWidth = displayWidth - tempX;
						stepWidth = Math.min(w - startX + tX, stepWidth);
						node.drawData.push(batchTexture.$bitmapX + tempX + s._repeatX, batchTexture.$bitmapY + paddingY + s._repeatY,stepWidth/sclX,stepHeight/sclY,batchTexture.$offsetX + startX,batchTexture.$offsetY + startY,stepWidth,stepHeight);						
						++node.renderCount;
						startX += stepWidth;
						if(tempX > 0)						
							tempX = 0;												
					}
					
					startY += stepHeight;
					if(paddingY > 0)									
						paddingY = 0;											
				}								
			}
			else
			{
				sclX = s._renderMatrix.a;
				sclY = s._renderMatrix.d;
				node.drawData.push(batchTexture.$bitmapX -s._renderMatrix.tx+tX, batchTexture.$bitmapY -s._renderMatrix.ty+tY,w/sclX,h/sclY,batchTexture.$offsetX + tX,batchTexture.$offsetY + tY,w,h);
				++node.renderCount;
			}			
			s.$renderDirty = true;
		}
		public clearBitmapFill():void
		{
			var s = this;
			var node:any = s.$renderNode;			
			node.cleanBeforeRender();
		}
		
		public set repeatWidth(val:number)
		{
			this._repeatWidth = val;
		}
		/**重复模式的砖块宽度*/
		public get repeatWidth():number
		{
			return this._repeatWidth;
		}
		public set repeatHeight(val:number)
		{
			this._repeatHeight = val;
		}
		/**重复模式的砖块高度*/
		public get repeatHeight():number
		{
			return this._repeatHeight;
		}
		public set repeatX(val:number)
		{
			this._repeatX = val;
		}
		/**重复模式的起始X*/
		public get repeatX():number
		{
			return this._repeatX;
		}
		public set repeatY(val:number)
		{
			this._repeatY = val;
		}
		/**重复模式的起始Y*/
		public get repeatY():number
		{
			return this._repeatY;
		}
		public set width(val:number)
		{
			let s = this;
			if(s._width == val)
				return;
			s._width = val;
			egret.superSetter(GYBitmap,s,"width",val);
			s.invalidDraw();
		}
		public get width():number
		{
			let s = this;
			return s._width==s._width?s._width:(s.$texture?s.$texture.textureWidth:0);
		}
		
		public set height(val:number)
		{
			let s = this;
			if(s._height == val)
				return;
			s._height=val;			
			egret.superSetter(GYBitmap,s,"height",val);
			s.invalidDraw();
		}
		public get height():number
		{
			let s = this;
			return s._height==s._height?s._height:(s.$texture?s.$texture.textureHeight:0);
		}
		public set scale9GridRect(value:Scale9GridRect) 
		{
			let s = this;
			if(s._scale9GridRect == value)
				return;
			s._scale9GridRect=value;
			s.invalidDraw();
		}		
		/**绘制模式 @see ScaleMode
		 * @param val 0 拉伸 1 裁切 2 重复 */
		public set mode(val:number)
		{
			let s = this;
			if(s._mode == val)return;
			s._mode=val;
			if(egret.nativeRender)return;
			s.$renderNode = (s._mode == ScaleMode.FREE?new egret.sys.NormalBitmapNode():new egret.sys.BitmapNode);			
			s.invalidDraw();
		}
		public get mode():number
		{
			let s = this;
			return s._mode;
		}
		public set clipX(val:number)
		{
			let s = this;
			if(s._clipX == val)
				return;
			s._clipX = val;
			s.invalidDraw();
		}
		public set clipY(val:number)
		{
			let s = this;
			if(s._clipY == val)
				return;
			s._clipY = val;
			s.invalidDraw();
		}
		/**裁切的s.x坐标*/
		public get clipX():number
		{
			let s = this;
			return s._clipX;	
		}
		/**裁切的s.y坐标*/
		public get clipY():number
		{
			let s = this;
			return s._clipY;
		}
		public set drawX(val:number)
		{
			let s = this;
			if(s._drawX == val)
				return;
			s._drawX = val;
			s.invalidDraw();
		}
		public set drawY(val:number)
		{
			let s = this;
			if(s._drawY == val)
				return;
			s._drawY = val;
			s.invalidDraw();
		}
		/**绘制点的s.x坐标*/
		public get drawX():number
		{
			let s = this;
			return s._drawX;	
		}
		/**绘制点的s.y坐标*/
		public get drawY():number
		{
			let s = this;
			return s._drawY;
		}
		
		/**刷新绘图*/
		public invalidDraw():void
		{
			let s = this;
			if(s._invalidDraw)
				return;
			s._invalidDraw = true;
			// s.displayChg(s.updateView);
			LayoutManager.addRenderFunc(s);
		}

		public get scale9GridRect():Scale9GridRect
		{
			let s = this;
			return s._scale9GridRect;
		}

		public _disposed:boolean;
		public get disposed():boolean
		{
			return this._disposed;
		}
		public dispose():void
		{
			let s = this;			
			if(s._disposed)
				return;
			s._disposed = true;
			s.$setTexture(null);
		}
    }
}